﻿namespace Yaaf.WP7.NativeAccess.IO
{
    using System;
    using System.Diagnostics;
    using System.IO;
    using System.IO.IsolatedStorage;

    public class StreamWrapper : Stream
    {
        private readonly IsolatedStorageFileStream openFile;

        private readonly string originalPath;

        private readonly string tempPath;

        private bool changedSomething;
        
        private bool isDisposed;

        protected override void Dispose(bool disposing)
        {
            if (isDisposed)
            {
                return;
            }
            if (disposing)
            {
                openFile.Dispose();
                if (changedSomething)
                {
                    try
                    {
                        IO.File.Copy(this.tempPath, originalPath, true);
                    }
                    catch (UnauthorizedAccessException e)
                    {
                        Console.WriteLine("Error: " + e); 
                        if (Debugger.IsAttached)
                        {
                            Debugger.Break();
                        }
                    }
                    catch (IOException e)
                    {
                        // DO not throw in Dispose!
                        Console.WriteLine("Error: " + e); 
                        if (Debugger.IsAttached)
                        {
                            Debugger.Break();
                        }
                    }
                }

                try
                {
                    IO.File.Delete(this.tempPath);
                }
                catch(UnauthorizedAccessException e)
                {
                    Console.WriteLine("Error: " + e);
                }
                catch (IOException e)
                {
                    // DO not throw in Dispose!
                    Console.WriteLine("Error: " + e);
                }
                isDisposed = true;
            }

            base.Dispose(disposing);
        }
        public StreamWrapper(IsolatedStorageFileStream openFile, string originalPath, string tempPath)
        {
            this.openFile = openFile;
            this.originalPath = originalPath;
            this.tempPath = tempPath;
        }

        public override void Flush()
        {
            this.openFile.Flush();

            if (changedSomething)
            {
                IO.File.Copy(this.tempPath, originalPath, true);
                changedSomething = false;
            }
        }

        public override long Seek(long offset, SeekOrigin origin)
        {
            return this.openFile.Seek(offset, origin);
        }

        public override void SetLength(long value)
        {
            changedSomething = true;
            openFile.SetLength(value);
        }

        public override int Read(byte[] buffer, int offset, int count)
        {
            return openFile.Read(buffer, offset, count);
        }

        public override void Write(byte[] buffer, int offset, int count)
        {
            openFile.Write(buffer, offset, count);
            if (count > 0)
            {
                changedSomething = true;
            }
        }

        public override bool CanRead
        {
            get
            {
                return openFile.CanRead;
            }
        }

        public override bool CanSeek
        {
            get
            {
                return openFile.CanSeek;
            }
        }

        public override bool CanWrite
        {
            get
            {
                return openFile.CanWrite;
            }
        }

        public override long Length
        {
            get
            {
                return openFile.Length;
            }
        }

        public override long Position
        {
            get
            {
                return openFile.Position;
            }
            set
            {
                openFile.Position = value;
            }
        }
    }
}